﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Audio;

namespace hamster.WorldObjects
{
    class Leaf : WorldObject
    {
        public const float RUSTLE_TIME = 3;
        public const float MOVEMENT_AMOUNT = (float)Math.PI / 8;
        public const float LEAF_SIZE = .4f;
        public const float LEAF_SCALE_VARIANCE = 0.2f;
        public const float GROWTH_TIME = .6f;
        public const float GROWTH_DISTANCE = 100f;
        private float rustleTime_;
        private float rustlingVal_;
        private float leafSize_;
        public float initialGrowth_;
        private Plant parentPlant_;
        private int orientation_;
        private bool isColliding_;

        //Sound
        SoundEffect se_rustle;

        public Leaf(Vector2 position, float rotation, ObjectPlacer parent, Plant parentPlant)
            : base(position, rotation, parent)
        {
            debugColor_ = Color.Green;
            leafSize_ = 1.25f + LEAF_SCALE_VARIANCE * Game1.RandomNegPos();
            objectScale_ = LEAF_SIZE * leafSize_;
            rustlingVal_ = 0;
            initialGrowth_ = 0;
            localTransformations_ = Matrix.CreateScale(0);
            parent_ = parent;
            parentPlant_ = parentPlant;
            orientation_ = (Game1.random.NextDouble() < 0.5) ? 1 : -1;
            isColliding_ = false;

            //Sound
            se_rustle = Game1._player.g.Content.Load<SoundEffect>("Sounds\\rustle");
        }

        public bool Update(float dt, Player player, Matrix plantTransformations, bool prevGrown)
        {
            base.Update(dt, player);

            if (prevGrown && initialGrowth_ < 1 && Vector2.Distance(new Vector2(player.position.X, player.position.Y), position_) <= GROWTH_DISTANCE)
                initialGrowth_ += dt / GROWTH_TIME;
            initialGrowth_ = MathHelper.Clamp(initialGrowth_, 0, 1);
            float leafScale = leafSize_ * initialGrowth_;
            localTransformations_ *= plantTransformations;
            float translation = -1-LEAF_SIZE;
            localTransformations_ *= Matrix.CreateTranslation(0, translation, 0);
            localTransformations_ *= Matrix.CreateScale(leafScale * orientation_, leafScale, leafScale);
            localTransformations_ *= Matrix.CreateTranslation(0, -translation, 0);
            // If the player hits the plant, rustle the plant THEN DELETE THAT FUCKER
            if (player.isMoving && boundingBox_.Intersects(player.boundingBox) && rustlingVal_ == 0)
            {
                if (!isColliding_)
                {
                    rustleTime_ = (RUSTLE_TIME / 2 + RUSTLE_TIME) * Game1.RandomNegPos();
                    rustlingVal_ = rustleTime_;
                    isColliding_ = true;
                    se_rustle.Play();
                    //parent_.CreateWaste(player);
                    //parentPlant_.RemoveLeaf(this);
                }
                rustleTime_ = (RUSTLE_TIME / 2 + RUSTLE_TIME) * Game1.RandomNegPos();
                rustlingVal_ = rustleTime_;
                //parent_.CreateWaste(player);
                //parentPlant_.RemoveLeaf(this);
            }
            else
            {
                isColliding_ = false;
            }

            if (rustlingVal_ > 0)
            {
                rustlingVal_ = Game1.StepCloserToZero(rustlingVal_, dt);
                float rotation = (float)Math.Sin(MathHelper.TwoPi * rustlingVal_ / rustleTime_);
                rotation = rotation * MOVEMENT_AMOUNT;

                localTransformations_ *= Matrix.CreateTranslation(LEAF_SIZE / 2, -1-LEAF_SIZE, 0);
                localTransformations_ *= Matrix.CreateRotationZ(rotation);
                localTransformations_ *= Matrix.CreateTranslation(-LEAF_SIZE / 2, 1+LEAF_SIZE, 0);
            }
            if (rustlingVal_ < 0)
                rustlingVal_ = 0;

            // Don't want to remove plant
            return false;
        }

        Vector4 color = new Vector4(Game1.RandomFloat, Game1.RandomFloat, Game1.RandomFloat, 0f) * 1.15f;
        float leaf_type = Game1.RandomFloat > 0.5f ? 1 : 0;
        public override void Draw(GraphicsDevice device)
        {
            //if (Keyboard.GetState().IsKeyDown(Keys.Space))
            //{
            //    color.X = Game1.RandomFloat ;
            //    color.Y = Game1.RandomFloat;
            //    color.Z = Game1.RandomFloat;
            //    color.W = 0;
            //    color *= 1.15f;
            //}

            ObjectPlacer._objectEffect.Parameters["Color"].SetValue(color);
            ObjectPlacer._objectEffect.Parameters["World"].SetValue(World);
            ObjectPlacer._objectEffect.Parameters["g_leaftype"].SetValue(leaf_type);
            
            ObjectPlacer._objectEffect.CommitChanges();
            device.DrawUserPrimitives<VertexPositionNormalTexture>(PrimitiveType.TriangleList, ObjectPlacer._quad, 0, ObjectPlacer._quad.Length / 3);

            /*
            Vector3 upDir = Vector3.Transform(Vector3.Up, Matrix.CreateRotationZ(rotation_));
            Game1.DrawDebugSquare(localTransformations_ * Matrix.CreateScale(objectScale_) * Matrix.CreateWorld(new Vector3(position_, -1), -Vector3.UnitZ, upDir), debugColor_); 
            */
            //Game1.spriteBatch.dr

            //base.Draw(device);
        }

        internal Fruit SpawnFruit()
        {
            Vector2 fruitPos = new Vector2(position_.X + Game1.RandomNegPos() * LEAF_SIZE, position_.Y + Game1.RandomNegPos() * LEAF_SIZE);
            return new Fruit(fruitPos, rotation_, parent_);
        }

        internal bool isGrown()
        {
            return initialGrowth_ == 1f;
        }
    }
}
